
#include "s3e.h"
#include "Iw2D.h"
#include "IwResManager.h"
#include "CelestialBody.h"

#define CELESTIALBODIES_COUNT 19

enum CelestialBodies {SUN,MERCURY,VENERA,EARTH,MOON,MARS,JUPITER,J1,J2,J3,SATURN,S1,S2,S3,S4,URAN,NEPTUN,PLUTON,P1};

// Scales the current graphics output
void SetRatio(double ratio) {
	if(ratio == 1) {
		Iw2DSetTransformMatrix(CIwMat2D::g_Identity);
	} else {
		CIwMat2D scale = CIwMat2D::g_Identity;		
		scale.Scale(IW_FIXED(ratio));
		Iw2DSetTransformMatrix(scale);
	}
}

// Application entry point
int main() {
	// libs initializations
	Iw2DInit();
	IwResManagerInit();

	IwGetResManager()->LoadGroup("textures.group");

	int displayWidth  = Iw2DGetSurfaceWidth();
	int displayHeight = Iw2DGetSurfaceHeight();

	// this way we create image object for background
	CIw2DImage* background = Iw2DCreateImageResource("cosmo"); 

	// all other images are created in this loop 
	CIw2DImage* celestialImgs[CELESTIALBODIES_COUNT];
	for(int i=0;i<CELESTIALBODIES_COUNT;i++) {
		char str[25]; sprintf(str,"image%03d",i+1);
		celestialImgs[i] = Iw2DCreateImageResource(str); 
	}

	// Celestial Bodies object abstractions, see the class code for more info
	CCelestialBody* celestialBodies[CELESTIALBODIES_COUNT];
	
	celestialBodies[SUN] = new CCelestialBody(displayWidth,displayHeight,celestialImgs[SUN]);
	celestialBodies[MERCURY] = new CCelestialBody(10,9,celestialImgs[MERCURY],celestialBodies[SUN],50,40,8);
	celestialBodies[VENERA] = new CCelestialBody(20,8,celestialImgs[VENERA],celestialBodies[SUN],70,60,-16);
	celestialBodies[EARTH] = new CCelestialBody(3,7,celestialImgs[EARTH],celestialBodies[SUN],120,90,20);
		celestialBodies[MOON] = new CCelestialBody(40,6,celestialImgs[MOON],celestialBodies[EARTH],20,20,3);
	celestialBodies[MARS] = new CCelestialBody(8,5,celestialImgs[MARS],celestialBodies[SUN],150,120,30);
	celestialBodies[JUPITER] = new CCelestialBody(60,4,celestialImgs[JUPITER],celestialBodies[SUN],170,140,104);
		celestialBodies[J1] = new CCelestialBody(40,6,celestialImgs[J1],celestialBodies[JUPITER],20,20,3);
		celestialBodies[J2] = new CCelestialBody(40,6,celestialImgs[J2],celestialBodies[JUPITER],25,25,9);
		celestialBodies[J3] = new CCelestialBody(40,6,celestialImgs[J3],celestialBodies[JUPITER],30,30,15);
	celestialBodies[SATURN] = new CCelestialBody(70,3,celestialImgs[SATURN],celestialBodies[SUN],230,180,190);
		celestialBodies[S1] = new CCelestialBody(40,6,celestialImgs[S1],celestialBodies[SATURN],20,20,3);
		celestialBodies[S2] = new CCelestialBody(40,6,celestialImgs[S2],celestialBodies[SATURN],25,25,6);
		celestialBodies[S3] = new CCelestialBody(40,6,celestialImgs[S3],celestialBodies[SATURN],30,30,15);
		celestialBodies[S4] = new CCelestialBody(40,6,celestialImgs[S4],celestialBodies[SATURN],35,35,25);
	celestialBodies[URAN] = new CCelestialBody(80,2,celestialImgs[URAN],celestialBodies[SUN],300,220,390);
	celestialBodies[NEPTUN] = new CCelestialBody(90,1,celestialImgs[NEPTUN],celestialBodies[SUN],350,250,600);
	celestialBodies[PLUTON] = new CCelestialBody(0,10,celestialImgs[PLUTON],celestialBodies[SUN],400,290,900);
		celestialBodies[P1] = new CCelestialBody(40,6,celestialImgs[P1],celestialBodies[PLUTON],10,10,3);


	uint32 timer = (uint32)s3eTimerGetMs();
	// application main loop
	while(!s3eDeviceCheckQuitRequest()) {
		s3eDeviceYield(0);

		// Calculate the amount of time which passed since last frame
		int delta = uint32(s3eTimerGetMs()) - timer;
		timer += delta;

		Iw2DSetColour(0xffffffff);
		Iw2DSetAlphaMode(IW_2D_ALPHA_NONE);
		double ratioH = 1;
		double ratioW = 1;
		if(background->GetWidth() < displayWidth) {
			ratioW = displayWidth / (double)(background->GetWidth());
		}
		if(background->GetHeight() < displayHeight) {
			ratioH = displayHeight / (double)(background->GetHeight());
		}
		double ratio = MAX(ratioH,ratioW);
		SetRatio(ratio);
		Iw2DDrawImage(background,CIwSVec2(0,0));
		SetRatio(0.5);

		for (int i=0;i<CELESTIALBODIES_COUNT;i++) {
			celestialBodies[i]->Update(delta);
			celestialBodies[i]->Render();
		}
		
		//Present the rendered surface to the screen
		Iw2DSurfaceShow();
	}

// clean up everything

	for(int i=0;i<CELESTIALBODIES_COUNT;i++) {
		delete celestialImgs[i];
		delete celestialBodies[i];
	}
	
	delete background;

	IwResManagerTerminate();
	Iw2DTerminate();
	
}